/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.netbeans.core; import java.io.*; import java.util.*; import java.beans.*; import java.net.*; import java.util.jar.Manifest; import java.util.ArrayList; import java.util.Collection; import java.util.ResourceBundle; import org.xml.sax.*; import org.xml.sax.helpers.*; import org.openide.TopManager; import org.openide.execution.*; import org.openide.filesystems.*; import org.openide.modules.*; import org.openide.util.io.*; import org.openide.util.NbBundle; import org.openide.NotifyDescriptor; import org.openide.DialogDescriptor; /** This class implementats the main functions which are needed for * installing of new module into the system and storage of them. * * @author Petr Hamernik, Jaroslav Tulach */ public final class ModuleInstaller extends Object { /** Tes ResourceBundle */ private static final ResourceBundle bundle = NbBundle.getBundle( ModuleInstaller.class ); /** resource string for initializer module manifest file */ private static final String MF_INITIALIZER = "/org/netbeans/core/resources/mf-initializer.txt"; // NOI18N /** name of file to contain stored externalizable modules */ private static final String EXTERNALIZED_MODULES = "externalizedModules.ser"; // NOI18N /** Instance of ModuleInstaller support */ private static ModuleInstallerSupport miSupport = null; /** Boolean property to remember if some modules were updated or disabled * to write new installedModules.xml during installing modules */ private static boolean writeRegistry = true; /** The only instance of the installer */ private static final PropertyChangeSupport INSTANCE = new PropertyChangeSupport (new ModuleInstaller ()); /** Private constructor */ private ModuleInstaller () { } // PUBLIC METHODS ------------------------------------------------------------ /** Adds listener on the nodes. */ public static void addPropertyChangeListener (PropertyChangeListener l) { INSTANCE.addPropertyChangeListener (l); } /** Removes listener on the nodes. */ public static void removePropertyChangeListener (PropertyChangeListener l) { INSTANCE.removePropertyChangeListener (l); } /** Getter for array of modules of given kind * @return array of modules */ public static ModuleItem[] getModuleItems ( int kind ) { Collection modules = miSupport.get( kind ); return (ModuleItem[])modules.toArray (new ModuleItem[ modules.size ()]); } /** Retruns array of module descriptions of installed modules */ public static ModuleDescription[] getModuleDescriptions( int kind ) { Collection modules = miSupport.get( kind ); ModuleItem[] items = (ModuleItem[])modules.toArray (new ModuleItem[ modules.size ()]); ModuleDescription[] result = new ModuleDescription[ items.length ]; for( int i = 0; i < items.length; i++ ) { result[i] = items[i].getDescription(); } return result; } /** Returns module item for name */ static ModuleItem getByName( String codeNameBase ) { return miSupport.get( codeNameBase ); } /** Initializes the modules loads the previously installed modules */ public synchronized static void initialize() { // System.out.println("LOADING MODULES ------------------------------- " ); //NOI18N miSupport = new ModuleInstallerSupport(); // Reads the miSupport // System.out.println( miSupport ); // Initalize actions pool ... ModuleActions.initialize(); Collection m2i = miSupport.get( miSupport.ENABLED_MODULE ); Collection orderedModules = null; // Sort enabled modules try { orderedModules = resolveOrdering( m2i ); } catch ( IllegalModuleException e ) { TopManager.getDefault().notifyException( e ); } if ( orderedModules == null ) { orderedModules = new ArrayList(); } // Look wther some modules have to be disabled Collection dm = miSupport.get( miSupport.ENABLED_MODULE ); dm.removeAll( orderedModules ); if ( !dm.isEmpty() ) { NotifyDescriptor nd = new NotifyDescriptor.Message( bundle.getString ("MSG_Some_Missed") + "\n" + getMissed( new ArrayList(), m2i ) ); TopManager.getDefault().notify( nd ); } // Print info if ( orderedModules.size() > 0 ) System.err.println (Main.getString ( "INFO_LoadedModules", moduleItemsDescr (m2i))); // Initialize module class loader initializeClassLoader( orderedModules ); // Instal IDE installIDEManifest(); // Add disabled modules to ordered modules orderedModules.addAll( dm ); // Install default sections of all modules { Iterator it = orderedModules.iterator (); while (it.hasNext ()) { ModuleItem mi = (ModuleItem)it.next (); TopManager.getDefault ().setStatusText (Main.getString ( "MSG_Install_Section", mi.getDescription ().getName ())); if ( dm.contains( mi ) ) { writeRegistry = true; mi.setEnabledNoNotify( false ); } else { mi.restoreSection (); mi.restoreDefault (); } } } // Tell loader pool node the installation is finished // No longer necessary: LoaderPoolNode.finishInstallation(); // Try to deexternalize modules try { deExternalizeModules(); } catch ( IOException e ) { TopManager.getDefault().notifyException( e ); } // Restored or Updated code of all modules { boolean someUpdated = false; Iterator it = orderedModules.iterator (); while (it.hasNext ()) { ModuleItem mi = (ModuleItem)it.next (); if (mi.isEnabled ()) { TopManager.getDefault ().setStatusText ( Main.getString ( "MSG_Install_Module", mi.getDescription ().getName ())); if ( mi.isUpdated() ) { mi.updatedCode(); } else { mi.restoreCode (); someUpdated = true; } } } if ( !writeRegistry ) writeRegistry = someUpdated; } // Fire module change INSTANCE.firePropertyChange (null, null, null); // If multiuser let's restore the new central modules if ( miSupport.isMultiuser() ) { //System.out.println("Loading mu -- restored" ); // NOI18N autoLoadModules( miSupport.AUTOLOAD_CENTRAL_MODULE ); } } /** Autoloads all modules into the system. This is called from Main and * installs new modules. In multiuser environment only the modules in USER directory * are installed. The modules from central directory are already restored * * This method also reads the modules for testing and installs them. The repository * is already restored so we can load the classes. */ public static synchronized void autoLoadModules () { if ( miSupport.isMultiuser() ) { autoLoadModules( miSupport.AUTOLOAD_USER_MODULE ); } else { //System.out.println(" loading standard - no multiuser " ); // NOI18N autoLoadModules( miSupport.AUTOLOAD_CENTRAL_MODULE | miSupport.AUTOLOAD_USER_MODULE ); } } public static synchronized void autoLoadModules ( int kind ) { // resort new modules Collection m2i = miSupport.get( kind ); Collection newModules = null; try { newModules = resolveOrdering ( m2i, miSupport.get( miSupport.ENABLED_MODULE | miSupport.DISABLED_MODULE ) ); } catch (IllegalModuleException e) { TopManager.getDefault ().notifyException (e); } Collection dm = miSupport.get( kind ); dm.removeAll( newModules ); if ( !dm.isEmpty() ) { NotifyDescriptor nd = new NotifyDescriptor.Message( bundle.getString ("MSG_Some_New_Missed") + "\n" + getMissed( miSupport.get( miSupport.ENABLED_MODULE ), m2i ) ); TopManager.getDefault().notify( nd ); } if ( newModules == null ) newModules = new ArrayList(); Collection modules4Check = miSupport.get( kind ); modules4Check.removeAll( dm ); Collection enModules = miSupport.checkDependenciesOnDisabled ( modules4Check ); if ( enModules != null && enModules.size() > 0) { StringBuffer sb = new StringBuffer(); sb.append( bundle.getString( "MSG_EnableToInstall") ); Iterator it = enModules.iterator(); while( it.hasNext() ) { sb.append ( ((ModuleItem)it.next() ).getDescription().getCodeName() ).append( "\n" ); // NOI18N } NotifyDescriptor nd = new NotifyDescriptor.Message( sb.toString() ); TopManager.getDefault().notify( nd ); it = enModules.iterator(); while( it.hasNext() ) { ((ModuleItem)it.next() ).setEnabled( true ); } } // Print information about installed modules ... if ( newModules.size () > 0) System.err.println (Main.getString ("INFO_InstalledModules", moduleItemsDescr ( newModules ))); // Add disabled modules to ordered modules newModules.addAll( dm ); try { { Iterator it = newModules.iterator (); while (it.hasNext ()) { ModuleItem mi = (ModuleItem)it.next (); TopManager.getDefault ().setStatusText (Main.getString ("MSG_Install_Section", mi.getDescription ().getName ())); if ( dm.contains( mi ) ) { mi.setEnabledNoNotify( false ); continue; } ModuleClassLoader.add ( mi.getLoaderURL() ); if ( miSupport.isMultiuser() && miSupport.getKind( mi ) == miSupport.AUTOLOAD_CENTRAL_MODULE ) mi.restoreSection(); else mi.installSection(); mi.restoreDefault(); } } // Install code of all modules ... { Iterator it = newModules.iterator (); while (it.hasNext ()) { ModuleItem mi = (ModuleItem)it.next (); TopManager.getDefault ().setStatusText (Main.getString ("MSG_Install_Module", mi.getDescription ().getName ())); if ( mi.isEnabled() ) { if ( miSupport.isMultiuser() && miSupport.getKind( mi ) == miSupport.AUTOLOAD_CENTRAL_MODULE ) mi.restoreCode(); else mi.installCode(); } // add the module to list of installed modules miSupport.remove( mi, miSupport.getKind( mi ) ); miSupport.add ( mi, miSupport.ENABLED_MODULE ); } } if ( !newModules.isEmpty() ) { TopManager.getDefault().setStatusText( Main.getString ( "MSG_Install_Complete", // NOI18N new Integer( newModules.size ()), ((ModuleItem)newModules.iterator().next()).getDescription().getName() )); INSTANCE.firePropertyChange (null, null, null); } } finally { } if ( !newModules.isEmpty () || writeRegistry ) { miSupport.writeRegistry(); } // Now is the time to install all test modules ClassLoaderSupport.resetLoader(); try { //addAllTestModules(); if ( !miSupport.get( miSupport.TEST_MODULE ).isEmpty() ) { Collection testModules = resolveOrdering ( miSupport.get( miSupport.TEST_MODULE ), miSupport.ENABLED_MODULE ); if ( testModules.isEmpty() ) { //System.out.println(" can't reorder modules " ); // NOI18N throw new IOException (); } Iterator it = testModules.iterator(); while( it.hasNext() ) { ModuleItem mi = (ModuleItem)it.next(); mi.restoreSection (); mi.restoreDefault (); mi.restoreCode(); //doAddModule( ((ModuleItem)it.next() ) ); } } } catch ( IOException e ) { TopManager.getDefault().notifyException( e ); } TopManager.getDefault().setStatusText( "" ); // NOI18N INSTANCE.firePropertyChange (null, null, null); } /** Instructs all modules to exit. * @return false if the exit should not continue */ public static boolean exit () { Collection enabledModules = miSupport.get( miSupport.ENABLED_MODULE ); Iterator it = enabledModules.iterator (); while (it.hasNext ()) { ModuleItem mi = (ModuleItem)it.next (); if (!mi.closing ()) { return false; } } try { externalizeModules (); } catch (IOException ex) { TopManager.getDefault ().notifyException (ex); } // No of the modules voted against exit notify it to modules it = enabledModules.iterator (); while (it.hasNext ()) { ModuleItem mi = (ModuleItem)it.next (); mi.closeCode (); } return true; } /** Installs module from file */ public synchronized static ModuleItem installFromFile (File file) throws IOException { int base = ModuleItem.BASE_JAR; if ( file.getParentFile().equals( miSupport.getCentralModuleDirectory() ) ) { base = ModuleItem.BASE_CENTRAL; } else if ( file.getParentFile().equals( miSupport.getUserModuleDirectory() ) ) { base = ModuleItem.BASE_USER; } ModuleItem mi = null; if ( base == ModuleItem.BASE_JAR ) mi = new ModuleItem( base, file.getPath(), true ); else mi = new ModuleItem( base, file.getName(), true ); ModuleItem exMi = miSupport.get( mi.getDescription().getCodeNameBase() ); if ( exMi != null ) { switch ( miSupport.getKind( exMi ) ) { case ModuleInstallerSupport.ENABLED_MODULE: case ModuleInstallerSupport.DISABLED_MODULE: case ModuleInstallerSupport.TEST_MODULE: NotifyDescriptor nd = new NotifyDescriptor.Message( bundle.getString( "MSG_Already_Installed" ) ); TopManager.getDefault().notify( nd ); return null; /* case ModuleInstallerSupport.DELETED_MODULE: miSupport.remove( exMi, miSupport.DELETED_MODULE ); */ } } if (resolveOrdering ( Collections.nCopies (1, mi), miSupport.ENABLED_MODULE | miSupport.DISABLED_MODULE ).isEmpty () ) { NotifyDescriptor.Message nd = new NotifyDescriptor.Message( bundle.getString( "MSG_Module_Missed" ) + "\n" + getMissed( miSupport.get( miSupport.ENABLED_MODULE | miSupport.DISABLED_MODULE ), Collections.nCopies (1, mi) ) ); TopManager.getDefault().notify( nd ); return null; //throw new IOException (); } Collection enModules = checkDependenciesOnDisabled ( mi.getDescription() ); if ( enModules != null ) { Iterator it = enModules.iterator(); while( it.hasNext() ) { ((ModuleItem)it.next() ).setEnabled( true ); } } else { return null; } doAddModule( mi ); miSupport.add( mi, miSupport.ENABLED_MODULE ); INSTANCE.firePropertyChange (null, null, null); miSupport.writeRegistry(); return mi; } static String getMissed( int kind, Collection installed ) { return getMissed( miSupport.get( kind ), installed ); } private static String getMissed( Collection restored, Collection installed ) { // List of messages for modules which are *not* to be installed. StringBuffer sb = new StringBuffer(); List missed = new ArrayList (); // List<String> // Set of modules which will actually be installed. Set actual = new HashSet (); // Set<ModuleDescription> actual.addAll (installed); int misscount; // this time around do { misscount = 0; Iterator it = actual.iterator (); while (it.hasNext ()) { ModuleDescription test = ((ModuleItem) it.next ()).getDescription(); Set whatCanIStillUse = new HashSet (); // Set<ModuleDescription> //whatCanIStillUse.addAll (restored); Iterator it2 = restored.iterator(); while (it2.hasNext ()) whatCanIStillUse.add( ((ModuleItem) it2.next ()).getDescription() ); // whatCanIStillUse.addAll (actual); it2 = actual.iterator(); while (it2.hasNext ()) whatCanIStillUse.add( ((ModuleItem) it2.next ()).getDescription() ); try { String miss = test.reasonWhyUnsatisfied ((ModuleDescription[]) whatCanIStillUse.toArray (new ModuleDescription[0])); if (miss != null) { misscount++; it.remove (); missed.add (miss); sb.append( miss ).append( "\n" ); // NOI18N } } catch ( org.openide.modules.IllegalModuleException e ) {} } } while (misscount > 0); if (missed.size () > 0) { return sb.toString(); /* System.out.println( missed ); return java.text.MessageFormat.format (bundle.getString ("MSG_Some_Missed") + "\n", new Object[] { (String[]) missed.toArray (new String[missed.size()] ) } ); */ } return null; } /** Deletes a module with given by ModuleItem parameter. * @return true if the module was removed, false if it was not installed */ public synchronized static boolean deleteModule( ModuleItem item ) { if (item != null ) { int kind = miSupport.getKind( item ); if ( kind != miSupport.ENABLED_MODULE && kind != miSupport.DISABLED_MODULE && kind != miSupport.TEST_MODULE ) return false; if ( item.canDestroy() ) { doRemoveModule (item); miSupport.remove( item, kind ); // item.setDeleted( true ); // miSupport.add( item, miSupport.DELETED_MODULE ); INSTANCE.firePropertyChange (null, null, null); miSupport.writeRegistry(); } else { item.setEnabled( false ); } return true; } else { return false; } } /** Changes the enabled status */ static synchronized void changeEnabled (ModuleItem item) { if (item.isEnabled ()) { doAddModule (item); } else { doRemoveModule (item); } miSupport.writeRegistry(); } /** Checks for dependencies on disabled modules. If the module depends on * some disabled modules then the method returns collection of modules which * should be enabled. If there are some other unsatisfied dependencies it returns * null. If there are no problems it returns empty Collection. */ static Collection checkDependenciesOnDisabled( ModuleDescription md ) { return askAndOrderToEnable( miSupport.checkDependenciesOnDisabled( md ) ); } static Collection checkDependenciesOnDisabled( Collection moduleItems ) { return askAndOrderToEnable( miSupport.checkDependenciesOnDisabled( moduleItems ) ); } // PRIVATE METHODS ----------------------------------------------------------- /** Initializes ModuleClassLoader with the given set of modules */ private static void initializeClassLoader( Collection modules ) { // Initialize module patches: List patches = new LinkedList (); // List<URL> FilenameFilter filter = new FilenameFilter () { public boolean accept (File dir, String name) { return name.toLowerCase ().endsWith ("jar") || name.toLowerCase ().endsWith ("zip"); // NOI18N } }; boolean debug = Boolean.getBoolean ("netbeans.debug.exceptions"); // NOI18N try { String nbUser = System.getProperty ("netbeans.user"); if (nbUser != null) { File[] files = new File (nbUser, "modules" + File.separatorChar + "patches").listFiles (filter); // NOI18N if (files != null) { for (int i = 0; i < files.length; i++) { patches.add (files[i].toURL ()); if (debug) System.err.println("Modules patch: " + files[i]); } } } String nbHome = System.getProperty ("netbeans.home"); if (nbHome != null && ! nbHome.equals (nbUser)) { File[] files = new File (nbHome, "modules" + File.separatorChar + "patches").listFiles (filter); // NOI18N if (files != null) { for (int i = 0; i < files.length; i++) { patches.add (files[i].toURL ()); if (debug) System.err.println("Modules patch: " + files[i]); } } } } catch (MalformedURLException mfurle) { if (Boolean.getBoolean ("netbeans.debug.exceptions")) // NOI18N mfurle.printStackTrace (); } URL[] names = new URL[patches.size () + modules.size ()]; patches.toArray (names); Iterator it = modules.iterator (); int i = patches.size (); while (it.hasNext ()) { ModuleItem mi = (ModuleItem)it.next (); names[i++] = mi.getLoaderURL (); } ModuleClassLoader.initialize (names); } /** Installs the IDE Manifest */ private static void installIDEManifest() { ModuleDescription ideDescr; try { ideDescr = new ModuleDescription(MF_INITIALIZER, new Manifest(ModuleInstaller.class.getResourceAsStream(MF_INITIALIZER)) ); } catch (Exception ex) { ex.printStackTrace (); throw new InternalError("Cannot install initializer manifest: " + ex); // NOI18N } ideDescr.forEachSection (ModuleItem.RESTORE); } /** Get a brief localized string describing a ModuleItem. */ private static String moduleItemDescr (ModuleItem item) { String spec = item.getDescription ().getSpecVersion (); String impl = item.getDescription ().getImplVersion (); java.text.MessageFormat mf = new java.text.MessageFormat(Main.getString ("INFO_ModuleSummary")); return mf.format (new Object[] { item.getDescription ().getCodeName (), spec == null ? Main.getString ("INFO_NullSpec") : spec, impl == null ? Main.getString ("INFO_NullImpl") : impl }); /* return Main.getString ("INFO_ModuleSummary", item.getDescription ().getCodeName (), spec == null ? Main.getString ("INFO_NullSpec") : spec); */ } /** Get a brief localized string describing a list of ModuleItem's. */ private static String moduleItemsDescr (Collection items) { StringBuffer buf = new StringBuffer (); Iterator it = items.iterator (); boolean first = true; while (it.hasNext ()) { if (first) first = false; else buf.append (Main.getString ("INFO_ModuleSummarySeparator")); buf.append (moduleItemDescr ((ModuleItem) it.next ())); } return buf.toString (); } /** @exception if something fails */ private static void doAddModule (ModuleItem item) { ModuleClassLoader.add (item.getLoaderURL ()); TopManager.getDefault ().setStatusText (Main.getString ("MSG_Install_Section", item.getDescription ().getName ())); item.installSection (); item.restoreDefault (); TopManager.getDefault ().setStatusText (Main.getString ("MSG_Install_Module", item.getDescription ().getName ())); item.installCode (); TopManager.getDefault ().setStatusText (Main.getString ("MSG_Install_Complete", new Integer (1), item.getDescription ().getName ())); System.err.println (Main.getString ("INFO_ModuleInstalled", moduleItemDescr (item))); } /** Removes a module. */ private static void doRemoveModule (ModuleItem item) { TopManager.getDefault ().setStatusText (Main.getString ("MSG_Uninstall_Module", item.getDescription ().getName ())); item.uninstallCode (); TopManager.getDefault ().setStatusText (Main.getString ("MSG_Uninstall_Section", item.getDescription ().getName ())); item.uninstallSection (); item.unrestoreDefault (); ModuleClassLoader.remove (item.getLoaderURL ()); TopManager.getDefault ().setStatusText (Main.getString ("MSG_Uninstall_Complete", new Integer (1), item.getDescription ().getName ())); System.err.println (Main.getString ("INFO_ModuleUninstalled", moduleItemDescr (item))); } /** Externalize modules. */ private static void externalizeModules () throws IOException { ObjectOutputStream os = new ObjectOutputStream ( new BufferedOutputStream ( new FileOutputStream ( new File ( miSupport.getUserModuleDirectory(), EXTERNALIZED_MODULES))) ); Iterator it = miSupport.get( miSupport.ENABLED_MODULE ).iterator(); while (it.hasNext ()) { ModuleItem mi = (ModuleItem)it.next (); try { NbObjectOutputStream.writeSafely (os, mi.getDescription ().getModule ()); } catch (SafeException ex) { if (System.getProperty ("netbeans.debug.exceptions") != null) { ex.getException ().printStackTrace(); } } } NbObjectOutputStream.writeSafely (os, null); NbObjectOutputStream.writeSafely (os, TopManager.getDefault ().getLoaderPool ()); os.close (); } /** Deexternalize modules. */ private static void deExternalizeModules () throws IOException { File f = new File ( miSupport.getUserModuleDirectory(), EXTERNALIZED_MODULES); if (!f.exists ()) { return; } ObjectInputStream is = new ObjectInputStream ( new BufferedInputStream (new FileInputStream (f)) ); for (;;) { try { if (NbObjectInputStream.readSafely (is) == null) { break; }; } catch (SafeException ex) { if (System.getProperty ("netbeans.debug.exceptions") != null) { ex.getException ().printStackTrace(); } } } try { // TopManager.getDefault ().getLoaderPool () NbObjectInputStream.readSafely (is); } catch (EOFException ex) { // this object has not been saved before => ignore } catch (SafeException ex) { if (System.getProperty ("netbeans.debug.exceptions") != null) { ex.getException ().printStackTrace(); } } is.close (); } static Collection resolveOrdering( Collection in, int kind ) { return resolveOrdering( in, kind, false ); } static Collection resolveOrdering( Collection in, int kind, boolean containsIn ) { Collection installed = miSupport.get( kind ); if ( containsIn ) { installed.removeAll( in ); } try { Collection result = resolveOrdering( in, installed ); return result; } catch ( IllegalModuleException e ) { TopManager.getDefault().notifyException( e ); return new ArrayList(); } } /** Reordres module to folow the dependencies. * * @param in collection of ModuleItems to install * @return list of module items */ private static List resolveOrdering (Collection in) throws IllegalModuleException { return resolveOrdering (in, new ArrayList() ); } /** Reordres module to folow the dependencies. * * @param in collection of ModuleItems to install * @param current current modules * @return list of module items * @exception IllegalModuleException if the modules are not ok. */ private static List resolveOrdering (Collection in, Collection current) throws IllegalModuleException { HashMap map = new HashMap (in.size ()); // Map (ModuleDescription, ModuleItem) Iterator it = in.iterator (); while (it.hasNext ()) { ModuleItem mi = (ModuleItem)it.next (); map.put (mi.getDescription (), mi); } List descr; if (current == null) { descr = ModuleDescription.resolveOrdering (map.keySet ()); } else { it = current.iterator (); HashSet s = new HashSet (); // set of descriptions while (it.hasNext ()) { ModuleItem mi = (ModuleItem)it.next (); s.add (mi.getDescription ()); } descr = ModuleDescription.resolveOrderingForRealInstall (s, map.keySet ()); } List out = new ArrayList (in.size ()); // List (ModuleItem) it = descr.iterator (); while (it.hasNext ()) { out.add (map.get (it.next ())); } return out; } private static Collection askAndOrderToEnable( Collection modules ) { if ( modules == null ) { return null; } if ( modules.size() == 0 ) return modules; StringBuffer sb = new StringBuffer( 200 ); sb.append( bundle.getString( "MSG_EnableOthers" ) ).append( "\n" ); Iterator it = modules.iterator(); while( it.hasNext() ) { sb.append( ((ModuleItem)it.next()).getDescription().getCodeNameBase() ); sb.append( "\n" ); // NOI18N } NotifyDescriptor nd = new NotifyDescriptor.Confirmation( sb.toString(), NotifyDescriptor.OK_CANCEL_OPTION ); TopManager.getDefault().notify( nd ); if ( nd.getValue() == DialogDescriptor.CANCEL_OPTION ) return null; else { Collection orderedModules = null; // Order the modules to enable try { orderedModules = resolveOrdering( modules, miSupport.get( ModuleInstallerSupport.ENABLED_MODULE ) ); return orderedModules; } catch ( IllegalModuleException e ) { TopManager.getDefault().notifyException( e ); return null; } } } // ---------------- Methods for modules testing /** Installs new module for testing */ static synchronized void installTestModule( ModuleItem mi ) throws IOException { boolean needToRestart = false; // Check wether the module already exists and is enabled ModuleItem exMi = miSupport.get( mi.getDescription().getCodeNameBase() ); if ( exMi != null ) { switch ( miSupport.getKind(exMi) ) { case ModuleInstallerSupport.ENABLED_MODULE: case ModuleInstallerSupport.DISABLED_MODULE: NotifyDescriptor nc = new NotifyDescriptor.Confirmation( bundle.getString( "MSG_TestModuleExists" ), DialogDescriptor.YES_NO_OPTION ); TopManager.getDefault().notify( nc ); if ( nc.getValue() == DialogDescriptor.NO_OPTION ) { return; } else { doRemoveModule ( exMi ); miSupport.remove( exMi, miSupport.getKind(exMi) ); INSTANCE.firePropertyChange (null, null, null); miSupport.writeRegistry(); needToRestart = true; } break; case ModuleInstallerSupport.TEST_MODULE: NotifyDescriptor nd = new NotifyDescriptor.Message( bundle.getString( "MSG_Test_Already_Installed" ) ); TopManager.getDefault().notify( nd ); return; } } // CheckDependencies if ( resolveOrdering (Collections.nCopies (1, mi), miSupport.ENABLED_MODULE | miSupport.TEST_MODULE ).isEmpty ()) { NotifyDescriptor.Message nd = new NotifyDescriptor.Message( bundle.getString( "MSG_Module_Missed" ) + "\n" + getMissed( miSupport.get( miSupport.ENABLED_MODULE | miSupport.DISABLED_MODULE ), Collections.nCopies (1, mi) ) ); TopManager.getDefault().notify( nd ); return; //throw new IOException (); } // Check disabled dependencies Collection enModules = checkDependenciesOnDisabled ( mi.getDescription() ); if ( enModules != null ) { Iterator it = enModules.iterator(); while( it.hasNext() ) { ((ModuleItem)it.next() ).setEnabled( true ); } } else { return; } removeAllTestModules(); ClassLoaderSupport.resetLoader (); miSupport.add( mi, miSupport.TEST_MODULE ); addAllTestModules(); //doAddModule( mi ); //miSupport.add( mi, miSupport.TEST_MODULE ); INSTANCE.firePropertyChange (null, null, null); miSupport.writeRegistry(); if ( needToRestart ) { NotifyDescriptor nd = new NotifyDescriptor.Message( bundle.getString( "MSG_Need_To_Restart" ) ); TopManager.getDefault().notify( nd ); } return; } /** Removes all test modules */ private static void removeAllTestModules() throws IOException { if ( miSupport.get( miSupport.TEST_MODULE ).isEmpty() ) return; Collection testModules = resolveOrdering ( miSupport.get( miSupport.TEST_MODULE ), miSupport.ENABLED_MODULE ); if ( testModules.isEmpty() ) { throw new IOException ( "Can't reorder modules" ); //NOI18N } Iterator it = testModules.iterator(); while( it.hasNext() ) { TestModuleItem tmi = ((TestModuleItem)it.next() ); doRemoveModule( tmi ); tmi.resetDescription(); } } /** Adds all test modules */ private static void addAllTestModules() throws IOException { if ( miSupport.get( miSupport.TEST_MODULE ).isEmpty() ) return; Collection testModules = resolveOrdering ( miSupport.get( miSupport.TEST_MODULE ), miSupport.ENABLED_MODULE ); if ( testModules.isEmpty() ) { throw new IOException ( "can't reorder modules" ); //NOI18N } Iterator it = testModules.iterator(); while( it.hasNext() ) { doAddModule( ((ModuleItem)it.next() ) ); } TopManager.getDefault().setStatusText( "" ); // NOI18N } /** Reinstalls all test modules */ static synchronized void reinstallTestModules() throws IOException { removeAllTestModules(); ClassLoaderSupport.resetLoader (); addAllTestModules(); INSTANCE.firePropertyChange (null, null, null); } /* static synchronized boolean removeTestModule( ModuleItem mi ) { ClassLoaderSupport.resetLoader (); ModuleItem item = findModule ( mi.getDescription().getCodeNameBase() ); if (item != null && modules.remove (item)) { doRemoveModule (item); INSTANCE.firePropertyChange (null, null, null); try { writeInstalledModules (); } catch (IOException e) { } return true; } else { return false; } return true; } */ /* Utility method gets all modules dependent on the module */ static Collection getDependentModules( ModuleItem item ) { return miSupport.getDependentModules( item.getDescription(), miSupport.ENABLED_MODULE ); } } /* * Log * 70 Gandalf 1.69 3/9/00 Petr Hrebejk The implementation * version of installed/restored modules is now written to the console * 69 Gandalf 1.68 1/19/00 Petr Nejedly Commented out debug * messages * 68 Gandalf 1.67 1/16/00 Jaroslav Tulach Faster startup. * 67 Gandalf 1.66 1/16/00 Ian Formanek NOI18N * 66 Gandalf 1.65 1/15/00 Petr Hrebejk Restoring of modules * from cetral directory in multiuser moved before opening of MainWindow * - mk1 * 65 Gandalf 1.64 1/13/00 Petr Hrebejk i18n * 64 Gandalf 1.63 1/13/00 Jesse Glick Modules patch printlns. * 63 Gandalf 1.62 1/13/00 Jesse Glick Module patch dirs. * 62 Gandalf 1.61 1/7/00 Petr Hrebejk Messages added to * enabling modules and installing from file * 61 Gandalf 1.60 1/6/00 Petr Hrebejk Bugfix * 60 Gandalf 1.59 1/5/00 Petr Hrebejk New module installer * 59 Gandalf 1.58 11/16/99 Petr Hrebejk Autoload works now even * with a test module installed * 58 Gandalf 1.57 11/10/99 Petr Hrebejk Unistalling/Disabling of * module now Uninstalls/Disables all dependent modules * 57 Gandalf 1.56 11/9/99 Petr Hrebejk Remove of last fix * 56 Gandalf 1.55 11/5/99 Petr Hrebejk More than one module can * be tested. * 55 Gandalf 1.54 11/1/99 Petr Hrebejk Multiuser installation * with MultiLayer filesystem first step * 54 Gandalf 1.53 10/29/99 Ian Formanek Removed obsoleted * imports * 53 Gandalf 1.52 10/29/99 Jesse Glick System.out -> System.err * for module info, so netbeans.log will get it. * 52 Gandalf 1.51 10/27/99 Petr Hrebejk Testing of modules added * 51 Gandalf 1.50 10/22/99 Ian Formanek NO SEMANTIC CHANGE - Sun * Microsystems Copyright in File Comment * 50 Gandalf 1.49 10/10/99 Petr Hamernik console debug messages * removed. * 49 Gandalf 1.48 10/7/99 Petr Hrebejk Versioning of modules in * installedModules.xml * 48 Gandalf 1.47 10/7/99 Petr Hrebejk * 47 Gandalf 1.46 10/5/99 Jaroslav Tulach Serializes differently * because it uses SharedClassObject serialization. * 46 Gandalf 1.45 9/30/99 Jesse Glick Brief log messages re. * module installation and uninstallation, for tech support purposes. Also * improved file chooser for New from File. * 45 Gandalf 1.44 9/30/99 Jaroslav Tulach DataLoader is now * serializable. * 44 Gandalf 1.43 8/27/99 Jesse Glick Better error message. * 43 Gandalf 1.42 8/20/99 Ian Formanek Uncommented debug * println on -Dnetbeans.manifest * 42 Gandalf 1.41 8/17/99 Petr Jiricka Installs loaders before * deexternalizing modules * 41 Gandalf 1.40 8/10/99 Ian Formanek removed debug printlns * 40 Gandalf 1.39 8/4/99 Petr Hrebejk One more multiuser * install fix * 39 Gandalf 1.38 8/3/99 Petr Hrebejk Multiuser update fix * 38 Gandalf 1.37 7/28/99 Jesse Glick -Dnetbeans.manifest=/foo/bar.mf:/baz/quux.mf * Can now use a colon to separate >1 manifest file, to test >1 module * at a time from Repository. Also ugly hack to make help set installation * work in this case. * 37 Gandalf 1.36 7/28/99 Jaroslav Tulach Additional manifest & * separation of actions by modules * 36 Gandalf 1.35 7/9/99 Jaroslav Tulach Add module from file * works better * 35 Gandalf 1.34 7/2/99 Jaroslav Tulach Enabled add module from * file * 34 Gandalf 1.33 6/8/99 Ian Formanek ---- Package Change To * org.openide ---- * 33 Gandalf 1.32 6/3/99 Jaroslav Tulach State of ModuleInstall * is stored if the object is also Externalizable. * 32 Gandalf 1.31 5/24/99 Jaroslav Tulach XML data object in Open * API * 31 Gandalf 1.30 5/16/99 Jaroslav Tulach Does not notify if * modules is not found * 30 Gandalf 1.29 5/13/99 Jaroslav Tulach Services. * 29 Gandalf 1.28 5/10/99 Jesse Glick Module versioning--IDE * version numbers refined, made into system properties. * 28 Gandalf 1.27 5/7/99 Jaroslav Tulach Help. * 27 Gandalf 1.26 5/6/99 Jaroslav Tulach Should load also * extensions. * 26 Gandalf 1.25 5/4/99 Jaroslav Tulach Checks dependencies. * 25 Gandalf 1.24 5/4/99 Jaroslav Tulach * 24 Gandalf 1.23 5/4/99 Jaroslav Tulach Relative URL for * modules. * 23 Gandalf 1.22 4/28/99 Jaroslav Tulach Checks for dependencies * between modules. * 22 Gandalf 1.21 4/28/99 Jaroslav Tulach XML storage for modules. * 21 Gandalf 1.20 4/19/99 Jaroslav Tulach Updating of modules * 20 Gandalf 1.19 4/8/99 Ian Formanek Changed Object.class -> * getClass () * 19 Gandalf 1.18 4/7/99 Ian Formanek Rename * Section->ManifestSection * 18 Gandalf 1.17 4/7/99 Ian Formanek Fixed last change * 17 Gandalf 1.16 4/7/99 Ian Formanek Updates Modules node * when modules change * 16 Gandalf 1.15 4/7/99 Ian Formanek Rename * Description->ModuleDescription * 15 Gandalf 1.14 3/30/99 Jaroslav Tulach Form loader before Java * loaderem. * 14 Gandalf 1.13 3/30/99 Jaroslav Tulach * 13 Gandalf 1.12 3/29/99 Ian Formanek Removed obsoleted * imports of ButtonBar * 12 Gandalf 1.11 3/29/99 Ian Formanek Modules are not loaded * into Hashtable to keep alphabetical order of installation * 11 Gandalf 1.10 3/26/99 Jaroslav Tulach * 10 Gandalf 1.9 3/26/99 Jaroslav Tulach * 9 Gandalf 1.8 3/24/99 Ian Formanek * 8 Gandalf 1.7 3/10/99 Jaroslav Tulach Modules from * autoloadfolder are restored not initialized * 7 Gandalf 1.6 3/9/99 Jaroslav Tulach ButtonBar * 6 Gandalf 1.5 2/18/99 David Simonek initializer manifest * added * 5 Gandalf 1.4 1/27/99 Jaroslav Tulach * 4 Gandalf 1.3 1/12/99 Jaroslav Tulach Modules are loaded by * URLClassLoader * 3 Gandalf 1.2 1/6/99 Ian Formanek Reflecting change in * datasystem package * 2 Gandalf 1.1 1/6/99 Ian Formanek Reflecting changes in * location of package "awt" * 1 Gandalf 1.0 1/5/99 Ian Formanek * $ */